<template>
  <base-modal
    :title="$t('common.base.bulkEdit')"
    :show.sync="visible"
    width="500px"
    class="provider-batch-edit-dialog"
    @closed="closeModel"
  >
    <batch-form :fields="fields" ref="batchForm" />

    <div slot="footer" class="dialog-footer">
      <el-button type="plain-third" @click="visible = false">{{$t('common.base.cancel')}}</el-button>
      <el-button type="primary" @click="onSubmit" :disabled="pending">{{$t('common.base.confirm')}}</el-button>
    </div>
  </base-modal>
</template>

<script>
import { FormFieldMap } from "@src/component/form/components";
import * as Utils from "@src/component/form/util";
import { safeNewDate } from '@src/util/time';
/* Api */
import FormItem from "@src/component/form/FormItem.vue";
import * as serviceProviderApi from "@src/api/serviceProviderApi";
import { isEmpty } from "lodash";
import { formatAddress, useFormTimezone } from 'pub-bbx-utils';

const { disposeFormSubmitTime } = useFormTimezone();

export default {
  name: "provider-batch-edit-dialog",
  props: {
    config: {
      type: Object,
      default: () => ({}),
    },
    selectedIds: {
      type: Array,
      default: () => [],
    },
  },
  data: () => {
    return {
      visible: false,
      pending: false,
      renderKey: ''
    };
  },
  watch: {
    visible(val) {
      if(val) {
        this.$refs.batchForm.reset();
      }
    }
  },
  computed: {
    fields() {
      const { fields } = this.config;
      const list = fields;
      let formTypes = ['attachment', 'separator', 'location', 'info', 'autograph', 'formula', 'logistics'];
      let isNotModify = ['text', 'textarea', 'number'];
      let isRepeat = ['text', 'textarea', 'number','phone'];

      
      let filterFields = list
      // 过滤 分割线、说明信息、位置、附件、电子签名、计算公式
      .filter(f => !formTypes.includes(f.formType))
      // 过滤 不允许修改的单行、多行、数字
      .filter(f => !(isNotModify.includes(f.formType) && f.setting.defaultValueConfig && !!f.setting.defaultValueConfig.isNotModify ))
      // 过滤 不允许重复的单行、多行、数字、电话
      .filter(f => !(isRepeat.includes(f.formType) && f.setting.isRepeat == 1))

      return filterFields;
    },
  },
  methods: {
    closeModel() {
      this.$refs.batchForm.reset();
    },
    open() {
      this.visible = true;
    },
    buildParams() {
      let tv = null;
      const { form, selectedField: sf } = this.$refs.batchForm.returnData();

      // 处理国际化时间转换
      const value = disposeFormSubmitTime([sf], form)
      let params = {
        mapJson: JSON.stringify({
          [sf.fieldName]: value[sf.fieldName]
        }),
        ids: this.selectedIds.join(","),
        fieldType: sf.isSystem,
      };

      if (sf.fieldName === "tags") {
        params.mapJson = JSON.stringify({
          [sf.fieldName]: form[sf.fieldName].map(({ id, tagName }) => ({
            id,
            tagName,
          })),
        });
      }
      if (sf.formType === "user") {
        tv = form[sf.fieldName];

        params.mapJson = JSON.stringify({
          [sf.fieldName]: {
            userId: tv.userId,
            displayName: tv.displayName,
            staffId: tv.staffId,
            head: tv.head
          },
        });
      }
      if (sf.fieldName === "manager") {
        tv = form[sf.fieldName];

        params.mapJson = JSON.stringify({
          [sf.fieldName]: {
            id: tv.userId,
            name: tv.displayName,
            staffId: tv.staffId,
          },
        });
      }

      if (sf.formType === "address") {
        tv = form[sf.fieldName];
        params.mapJson = JSON.stringify({
          [sf.fieldName]: {
            ...tv,
            all: formatAddress(tv,''),
          }
        });
      }

      if(sf.formType === 'planStartTime' || sf.formType === 'planEndTime'){
        params.mapJson = JSON.stringify({
          [sf.fieldName]: (form[sf.fieldName] && safeNewDate(form[sf.fieldName]).getTime()) || '',
        });
      }

      return params;
    },

    async onSubmit() {
      const { form, selectedField } = this.$refs.batchForm.returnData();
      let value = form[selectedField.fieldName]
      if(!selectedField?.isNull && isEmpty(value)) {
        this.$message.error(this.$t('common.validate.noNull'))
        return;
      }
      if(selectedField.fieldName === 'validTime' && value.length === 2) {
        value = {
          validTime: safeNewDate(value[0]).getTime(),
          inalidTime: safeNewDate(value[1]).getTime(),
        }
      }else if(selectedField.fieldName === 'role' && value.length) {
        value = value[0]
      }

      let params = {
        ids: this.selectedIds,
        displayName: selectedField.displayName,
        filedName: selectedField.fieldName,
        filedValue: value,
      };

      const res = await serviceProviderApi.batchUpdateProvider(params);
      this.$notify({
        title: this.$t('common.base.toast'),
        message:  res.success ?  this.$t('common.base.batchUpdateSuccess') : res.message,
        type: res.success ? 'success' : 'error',
      });

      this.visible = false;
      this.$emit("update");
    },
  },
  components: {
    BatchForm: {
      name: "batch-form",
      props: {
        fields: {
          type: Array,
          default: () => [],
        },
      },
      data: () => {
        return {
          selectedField: {},
          form: {},
        };
      },
      mounted() {
        this.reset();
      },
      methods: {
        /* 查询工单类型*/
        async fetchTaskType(params = {}) {
          try {
            let { keyword, pageNum, pageSize } = params;
            const dataToSend = {
              keyword,
              pageNum,
              pageSize
            };
            let res = await serviceProviderApi.searchTaskTypeList(dataToSend);
            if (!(res?.result)) return;
            let data = { // 目前工单没有分页，做成假的分页，以后接口修改直接修改这里
              total: res.result.length,
              hasNextPage: false,
            };
            data.list = this.handleTagData(res?.result);
            return data;
          }catch (error) {
            console.error('search dept error', error);
          }
        },
        /* 查询产品类型*/
        async fetchProductType(params = {}) {
          try {
            let { keyword, pageNum, pageSize } = params;
            const dataToSend = {
              keyword,
              pageNum,
              pageSize
            };
            let res = await serviceProviderApi.searchProductTypeList(dataToSend);
            if (!(res?.result?.list)) return;
            let total = 1;
            if(pageNum === 1 && res?.result?.list.length === 0){
              total = 0; // 目前产品类型查询接口不返回total,默认若查询不为空赋值total为1
            }
            res.result.list = this.handleTagData(res.result.list);
            res.result.total = total;
            return res.result;
          }catch (error) {
            console.error('search dept error', error);
          }
        },
        /* 查询角色*/
        async fetchRole(params = {}) {
          try {
            let { keyword } = params;
            const dataToSend = {
              roleName: keyword,
            };
            let res = await serviceProviderApi.getServiceRole(dataToSend);
            if (!(res?.data)) return;
            let data = { // 目前角色没有分页，做成假的分页，以后接口修改直接修改这里
              total: res.data.length,
              hasNextPage: false
            };
            data.list = this.handleTagData(res?.data);
            return data;
          }catch (error) {
            console.error('search dept error', error);
          }
        },
        /* biz-remote-select数据格式处理 */
        handleTagData(list) {
          let tagData = list.map(item => {
            return {
              label: (item && item.name) || '',
              value: (item && item.id.toString()) || '',
              id: (item && item.id.toString()) || '',
              name: (item && item.name) || '',
            }
          });
          return tagData;
        },

        returnData() {
          return {
            selectedField: this.selectedField,
            form: Object.assign({}, this.form),
          };
        },

        reset() {
          this.form = {};
          if (!this.fields.length) return
          this.selectField(this.fields[0].fieldName);
        },

        dispatch({ type, bubbles = false, params = {} }) {
          const _dom = Array.prototype.slice
            .call(this.$el.children)
            .filter((d) => /form-item/g.test(d.className))[0];
          _dom.dispatchEvent(
            new CustomEvent(type, { detail: params, bubbles })
          );
        },

        buildForm() {
          if (Object.keys(this.form).length === this.fields.length) return;
          this.form = Utils.initialize(this.fields);

          this.fields.forEach((f) => {
            if (['authorizeTask', 'authorizeProduct'].includes(f.fieldName)) {
              this.form[f.fieldName] = [];
            }
          });
        },

        update(event) {
          /**
           * 选择团队使用的是单独的组件，不是统一的form组件，所以更新时的返回值不同，需要特殊处理
           */
          if (['validTime', 'authorizeTask', 'authorizeProduct', 'role'].includes(this.selectedField.fieldName) ) {
            this.form[this.selectedField.fieldName] = event;
            return;
          }
          const f = event.field;
          this.form = { [f.fieldName]: event.newValue };
        },

        selectField(val) {
          this.buildForm()
          this.renderKey = val // form-item组件重新渲染

          this.selectedField = this.fields.filter(
            (f) => f.fieldName === val
          )[0];

          this.dispatch({
            type: "form.add.field",
            params: {
              value: () => this.form[this.selectedField.fieldName],
              field: this.selectedField,
              fieldName: this.selectedField.fieldName,
            },
          });

          this.dispatch({
            type: "form.clear.validate",
          });
        },

        renderSelector() {
          if (!this.fields) return null;
          return (
            <el-select
              value={this.selectedField.fieldName}
              placeholder={this.$t('common.placeholder.selectNeedChangeField')}
              onChange={this.selectField}
            >
              {this.fields.map((f) => (
                <el-option
                  key={f.fieldName}
                  label={f.displayName}
                  value={f.fieldName}
                ></el-option>
              ))}
            </el-select>
          );
        },

        renderInput(h) {
          const sf = this.selectedField;

          if (!sf.formType) return null;

          if (sf.fieldName === "validTime") {
            return h("el-date-picker", {
              props: {
                value: this.form[sf.fieldName],
                type: 'daterange',
                align: 'right',
                'unlink-panels': true,
                'range-separator': '-',
                'start-placeholder': this.$t('common.base.startDate'),
                'end-placeholder': this.$t('common.base.endDate')
              },
              on: {
                input: (event) => this.update(event),
              },
            });
          }else if (sf.fieldName === "role"){
            return h("biz-remote-select", {
              props: {
                value: this.form[sf.fieldName],
                field: sf,
                cleared: true,
                'remote-method': this.fetchRole,
                'placeholder': sf.placeHolder,
                'computed-width-keys': 'name',
              },
              on: {
                input: (event) => this.update(event),
              },
            });
          }else if (sf.fieldName === "authorizeTask"){
            return h("biz-remote-select", {
              props: {
                value: this.form[sf.fieldName],
                field: sf,
                cleared: true,
                multiple: true,
                'multiple-limit': 10,
                'remote-method': this.fetchTaskType,
                'placeholder': sf.placeHolder ||  this.$t('common.base.pleaseSelect'),
                'computed-width-keys': 'name',
              },
              on: {
                input: (event) => this.update(event),
              },
            });
          }else if (sf.fieldName === "authorizeProduct"){
            return h("biz-remote-select", {
              props: {
                value: this.form[sf.fieldName],
                field: sf,
                cleared: true,
                multiple: true,
                'multiple-limit': 10,
                'remote-method': this.fetchProductType,
                'placeholder': sf.placeHolder || this.$t('common.base.pleaseSelect'),
                'computed-width-keys': 'name',
              },
              on: {
                input: (event) => this.update(event),
              },
            });
          }

          const comp = FormFieldMap.get(sf.formType);
          const data = {
            props: {
              field: sf,
              value: this.form[sf.fieldName],
              placeholder: Utils.genPlaceholder(sf),
              seo: true
            },
            on: {
              update: (event) => this.update(event),
            },
          };

          return h(comp.build, data);
        },
      },
      render(h) {
        return (
          <div>
            <div class="item">
              <label class="form-name">{this.$t('common.base.modifyField')}</label>
              <div>{this.renderSelector()}</div>
            </div>
            <form-item label={this.$t('common.base.modifyTo')} propField={this.selectedField} key={this.renderKey}>{this.renderInput(h)}</form-item>
          </div>
        );
      },
    },
    components: {
      [FormItem.name]: FormItem,
    },
  },

};
</script>

<style lang="scss">
.provider-batch-edit-dialog {
  .base-modal-body {
    padding: 10px 30px 0;
  }

  .form-name,
  .form-item .form-item-label {
    width: 70px;
    padding: 0;
    line-height: 32px;
    margin-bottom: 10px;
  }

  .item {
    display: flex;
    justify-content: space-between;
    line-height: 32px;
    div {
      flex-grow: 1;
      .el-select {
        width: 100%;
      }
    }
  }

  .dialog-footer {
    display: flex;
    justify-content: flex-end;
  }
}
</style>
